package foo.bar.blog.core.services;

import com.sun.syndication.feed.synd.*;
import foo.bar.blog.core.domain.Blog;
import foo.bar.blog.core.domain.User;
import foo.bar.blog.core.domain.Entry;
import foo.bar.blog.radeox.DecoratedEntryTransformer;
import foo.bar.blog.web.action.general.BlogActionBean;
import foo.bar.blog.web.action.general.MainActionBean;
import foo.bar.radeox.api.engine.RenderEngine;

import java.util.List;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Collections;

import net.sourceforge.stripes.util.UrlBuilder;
import org.springframework.orm.jpa.JpaTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @author tmjee
 * @version $Date$ $Id$
 */
public class FeedsService extends AbstractFeedsService {

        private RenderEngine renderEngine;
        private BlogService blogService;

        FeedsService() {}

        public FeedsService(JpaTemplate jpaTemplate, RenderEngine renderEngine, BlogService blogService) {
            super(jpaTemplate);
            this.renderEngine = renderEngine;
            this.blogService = blogService;
        }


        public SyndFeed produceMainFeed(FeedType feedType) {
            List<Entry> entries = blogService.getLatestPublishedEntries();

            SyndFeed feed = new SyndFeedImpl();
            feed.setDescription("Latest Blog Entries");
            feed.setCopyright("Copyright FooBarBlog. Released Under Apache 2 License");
            feed.setEncoding("UTF-8");
            feed.setFeedType(feedType.toString());
            feed.setLanguage(Locale.getDefault().getLanguage());
            feed.setTitle("Latest Blog Entries");

            String blogUrl = buildMainUrl();
            feed.setLink(blogUrl);
            feed.setUri(blogUrl);

            SyndLink selfLink = new SyndLinkImpl();
            selfLink.setHref(feed.getUri());
            selfLink.setRel("self");
            feed.setLinks(Collections.singletonList(selfLink));

            // publishedDate
            if (entries != null && entries.size() > 0) {
                Entry latestEntry = (Entry) entries.iterator().next();
                if (latestEntry.getModificationDate() != null) {
                    feed.setPublishedDate(latestEntry.getModificationDate());
                }
                else {
                    feed.setPublishedDate(latestEntry.getCreationDate());
                }
            }
            List<SyndEntry> _entries = new ArrayList<SyndEntry>();
            for (Entry entry : entries) {
                SyndEntry syndEntry = new SyndEntryImpl();
                syndEntry.setAuthor(entry.getCreator().getUsername());

                List<SyndCategory> categories = new ArrayList<SyndCategory>();
                if (entry.getTag() != null) {
                    SyndCategory syndCategory = new SyndCategoryImpl();
                    syndCategory.setName(entry.getTag().getName());
                    categories.add(syndCategory);
                }
                syndEntry.setCategories(categories);


                List<SyndContent> contents = new ArrayList<SyndContent>();
                SyndContent syndContent = new SyndContentImpl();
                syndContent.setMode("text");
                syndContent.setType("text/plain");
                syndContent.setValue(new DecoratedEntryTransformer(renderEngine).transform(entry).getDecoratedContent());
                contents.add(syndContent);
                syndEntry.setContents(contents);

                List<SyndPerson> _contributors = new ArrayList<SyndPerson>();
                SyndPerson _syndPerson = new SyndPersonImpl();
                _syndPerson.setEmail(entry.getCreator().getEmail());
                _syndPerson.setName(entry.getCreator().getUsername());
                _contributors.add(_syndPerson);
                syndEntry.setContributors(_contributors);

                SyndContent _syndContent = new SyndContentImpl();
                _syndContent.setMode("text");
                _syndContent.setType("text/plain");
                _syndContent.setValue(entry.getDescription());
                syndEntry.setDescription(_syndContent);


                String entryUrl = buildEntryUrl(entry);
                syndEntry.setLink(entryUrl);

                SyndLink _syndLink = new SyndLinkImpl();
                _syndLink.setHref(syndEntry.getLink());
                _syndLink.setRel("self");
                syndEntry.setLinks(Collections.singletonList(_syndLink));

                syndEntry.setPublishedDate(entry.getCreationDate());
                syndEntry.setTitle(entry.getName());
                syndEntry.setUri(syndEntry.getLink());
                syndEntry.setUpdatedDate(entry.getModificationDate());

                _entries.add(syndEntry);
            }
            feed.setEntries(_entries);
            return feed;
        }

        protected String buildMainUrl() {
            UrlBuilder urlBuilder= new UrlBuilder(Locale.getDefault(), MainActionBean.class, false);
            urlBuilder.setEvent("view");
            return buildUrlPrefix()+urlBuilder.toString();
        }

        public SyndFeed produceBlogFeed(Blog blog, FeedType feedType) {

                SyndFeed feed = new SyndFeedImpl();

                // author
                feed.setAuthor(blog.getCreator().getUsername());

                // contributors
                List<SyndPerson> contributors = new ArrayList<SyndPerson>();
                if (blog.getMembers().size() > 0) {
                    for (User member : blog.getMembers()) {
                        SyndPerson p = new SyndPersonImpl();
                        p.setName(member.getUsername());
                        p.setEmail(member.getEmail());
                        contributors.add(p);
                    }
                }
                feed.setContributors(contributors);

                feed.setCopyright("Copyright FooBarBlog. Released Under Apache 2 License");
                feed.setDescription(blog.getDescription());
                feed.setEncoding("UTF-8");
                feed.setFeedType(feedType.toString());
                feed.setLanguage(Locale.getDefault().getLanguage());
                feed.setTitle(blog.getName());



                String blogUrl = buildBlogUrl(blog);
                feed.setLink(blogUrl);
                feed.setUri(blogUrl);

                SyndLink selfLink = new SyndLinkImpl();
                selfLink.setHref(feed.getUri());
                selfLink.setRel("self");
                feed.setLinks(Collections.singletonList(selfLink));

                // publishedDate
                if (blog.getEntries().size() > 0) {
                    Entry latestEntry = blog.getEntries().iterator().next();
                    if (latestEntry.getModificationDate() != null) {
                        feed.setPublishedDate(latestEntry.getModificationDate());
                    }
                    else {
                        feed.setPublishedDate(latestEntry.getCreationDate());
                    }
                }
                else if (blog.getModificationDate() != null) {
                    feed.setPublishedDate(blog.getModificationDate());
                }
                else {
                    feed.setPublishedDate(blog.getCreationDate());
                }

                List<SyndEntry> entries = new ArrayList<SyndEntry>();
                for (Entry entry : blog.getEntries()) {
                    SyndEntry syndEntry = new SyndEntryImpl();
                    syndEntry.setAuthor(entry.getCreator().getUsername());

                    List<SyndCategory> categories = new ArrayList<SyndCategory>();
                    if (entry.getTag() != null) {
                        SyndCategory syndCategory = new SyndCategoryImpl();
                        syndCategory.setName(entry.getTag().getName());
                        categories.add(syndCategory);
                    }
                    syndEntry.setCategories(categories);


                    List<SyndContent> contents = new ArrayList<SyndContent>();
                    SyndContent syndContent = new SyndContentImpl();
                    syndContent.setMode("text");
                    syndContent.setType("text/plain");
                    syndContent.setValue(new DecoratedEntryTransformer(renderEngine).transform(entry).getDecoratedContent());
                    contents.add(syndContent);
                    syndEntry.setContents(contents);

                    List<SyndPerson> _contributors = new ArrayList<SyndPerson>();
                    SyndPerson _syndPerson = new SyndPersonImpl();
                    _syndPerson.setEmail(entry.getCreator().getEmail());
                    _syndPerson.setName(entry.getCreator().getUsername());
                    _contributors.add(_syndPerson);
                    syndEntry.setContributors(_contributors);

                    SyndContent _syndContent = new SyndContentImpl();
                    _syndContent.setMode("text");
                    _syndContent.setType("text/plain");
                    _syndContent.setValue(entry.getDescription());
                    syndEntry.setDescription(_syndContent);


                    String entryUrl = buildEntryUrl(entry);
                    syndEntry.setLink(entryUrl);

                    SyndLink _syndLink = new SyndLinkImpl();
                    _syndLink.setHref(syndEntry.getLink());
                    _syndLink.setRel("self");
                    syndEntry.setLinks(Collections.singletonList(_syndLink));

                    syndEntry.setPublishedDate(entry.getCreationDate());
                    syndEntry.setTitle(entry.getName());
                    syndEntry.setUri(syndEntry.getLink());
                    syndEntry.setUpdatedDate(entry.getModificationDate());

                    entries.add(syndEntry);
                }
                feed.setEntries(entries);

                return feed;
        }

        protected String buildEntryUrl(Entry entry) {
            UrlBuilder _urlBuilder = new UrlBuilder(Locale.getDefault(), BlogActionBean.class, false);
            _urlBuilder.setEvent("viewEntry");
            _urlBuilder.addParameter("entry", entry.getId());
            return buildUrlPrefix()+_urlBuilder.toString();
        }

        protected String buildBlogUrl(Blog blog) {
            UrlBuilder urlBuilder = new UrlBuilder(Locale.getDefault(), BlogActionBean.class, false);
            urlBuilder.setEvent("view");
            urlBuilder.addParameter("blog", blog.getId());
            urlBuilder.addParameter("search", "null");
            urlBuilder.addParameter("selectedTag", "null");
            urlBuilder.addParameter("calendar", "null");
            return buildUrlPrefix()+urlBuilder.toString();
        }


        

}
